﻿using System;
using System.Configuration;
using System.IO;
using System.Windows;
using System.Xml.Serialization;
using ApartmentBillsManager.Start.Common;
using Microsoft.Win32;

namespace ApartmentBillsManager.Start.Services
{
    static class SaveLoadApartment
    {
        private static readonly Configuration Config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        private static readonly KeyValueConfigurationCollection Settings = Config.AppSettings.Settings;
        private static string _lastLoadedApartmentPath;

        private static readonly XmlSerializer ApartmentSerializer;

        private static readonly string MyApartmentsPath =
            Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\My Apartments";

        static SaveLoadApartment()
        {
            Directory.CreateDirectory(MyApartmentsPath);

            ApartmentSerializer = new XmlSerializer(typeof(Apartment));

            _lastLoadedApartmentPath = Settings["LastLoadedApartmentPath"].Value;
        }

        public static bool IsLastLoadedApartmentExists
        {
            get { return File.Exists(_lastLoadedApartmentPath); }
        }

        public static string LastLoadedApartmentPath
        {
            get { return _lastLoadedApartmentPath; }
            set
            {
                _lastLoadedApartmentPath = value;

                Settings["LastLoadedApartmentPath"].Value = _lastLoadedApartmentPath;

                Config.Save(ConfigurationSaveMode.Modified);

                ConfigurationManager.RefreshSection(Config.AppSettings.SectionInformation.Name);
            }
        }

        public static void SaveApartment(Apartment apartment)
        {
            File.WriteAllText(LastLoadedApartmentPath, string.Empty);

            using (var textWriter = new StreamWriter(LastLoadedApartmentPath))
            {
                ApartmentSerializer.Serialize(textWriter, apartment);

                MessageBox.Show(string.Format("Apartment file was saved to:\n{0}", LastLoadedApartmentPath));
            }
        }

        public static void SaveApartmentAs(Apartment apartment)
        {
            var saveFileDialog = new SaveFileDialog
                {
                    InitialDirectory = MyApartmentsPath,
                    RestoreDirectory = false,
                    Filter = "XML files (*.xml)|*.xml",
                    AddExtension = true,
                };

            saveFileDialog.ShowDialog();

            if (saveFileDialog.FileName != string.Empty)
            {
                File.WriteAllText(saveFileDialog.FileName, string.Empty);

                using (var textWriter = new StreamWriter(saveFileDialog.FileName))
                {
                    ApartmentSerializer.Serialize(textWriter, apartment);

                    MessageBox.Show(string.Format("Apartment file was saved to:\n{0}",
                                                  saveFileDialog.FileName));
                }

                UpdateLastLoadedApartment(saveFileDialog.FileName);
            }
        }

        public static Apartment LoadApartment()
        {
            var openFileDialog = new OpenFileDialog
                {
                    InitialDirectory = MyApartmentsPath,
                    Multiselect = false,
                    RestoreDirectory = false,
                    Filter = "XML files (*.xml)|*.xml"
                };

            openFileDialog.ShowDialog();

            if (openFileDialog.FileName != string.Empty)
            {
                try
                {
                    using (var file = openFileDialog.OpenFile())
                    {

                        var apartment = ApartmentSerializer.Deserialize(file) as Apartment;

                        if (apartment != null)
                        {
                            UpdateLastLoadedApartment(openFileDialog.FileName);

                            return apartment;
                        }
                    }

                }
                catch (InvalidOperationException e)
                {
                    MessageBox.Show("Invalid XML file.");
                }
            }

            return null;
        }

        public static Apartment LoadApartment(string path)
        {
            if (File.Exists(path))
            {
                try
                {
                    using (var file = File.OpenRead(path))
                    {

                        var apartment = ApartmentSerializer.Deserialize(file) as Apartment;

                        if (apartment != null)
                        {
                            UpdateLastLoadedApartment(path);

                            return apartment;
                        }
                    }

                }
                catch (InvalidOperationException)
                {
                    MessageBox.Show("Invalid XML file.");
                }
            }
            return null;
        }

        public static Apartment LoadLastLoadedApartment()
        {
            return LoadApartment(LastLoadedApartmentPath);
        }

        public static void ClearLastLoadedApartmentPath()
        {
            LastLoadedApartmentPath = string.Empty;
        }

        private static void UpdateLastLoadedApartment(string path)
        {
            LastLoadedApartmentPath = path;
        }
    }
}
